"""
状态缓存管理器
提供状态数据的缓存和快速访问功能
"""
from typing import Dict, List, Optional
from datetime import datetime, timedelta
import asyncio
from motor.motor_asyncio import AsyncIOMotorDatabase
from app.models.state import StateResponse, ModuleType


class StateCacheManager:
    """状态缓存管理器"""
    
    def __init__(self):
        self._cache: Dict[str, Dict[str, List[Dict[str, str | int | bool | None]] | int]] = {}
        self._cache_timestamps: Dict[str, datetime] = {}
        self._cache_ttl = timedelta(minutes=30)  # 缓存30分钟
        self._lock = asyncio.Lock()
    
    async def get_module_states(
        self, 
        db: AsyncIOMotorDatabase, 
        module_type: str,
        force_refresh: bool = False
    ) -> List[StateResponse]:
        """获取模块状态（带缓存）"""
        cache_key = f"module_states_{module_type}"
        
        async with self._lock:
            # 检查缓存是否有效
            if not force_refresh and self._is_cache_valid(cache_key):
                cached_data = self._cache.get(cache_key, {}).get("data", [])
                return [StateResponse(**state) for state in cached_data]
            
            # 从数据库获取最新数据
            cursor = db.states.find({"module_type": module_type}).sort("sort_order", 1)
            states = await cursor.to_list(length=None)
            
            # 转换为响应格式
            state_responses = []
            for state in states:
                state_response = StateResponse(
                    id=str(state["_id"]),
                    name=state["name"],
                    code=state["code"],
                    module_type=state["module_type"],
                    description=state.get("description"),
                    color=state.get("color", "#1890ff"),
                    icon=state.get("icon"),
                    sort_order=state.get("sort_order", 0),
                    is_enabled=state.get("is_enabled", True),
                    is_visible=state.get("is_visible", True),
                    is_default=state.get("is_default", False),
                    created_at=state.get("created_at"),
                    updated_at=state.get("updated_at")
                )
                state_responses.append(state_response)
            
            # 更新缓存
            self._cache[cache_key] = {
                "data": [state.model_dump() for state in state_responses],
                "count": len(state_responses)
            }
            self._cache_timestamps[cache_key] = datetime.utcnow()
            
            return state_responses
    
    async def get_state_by_code(
        self, 
        db: AsyncIOMotorDatabase, 
        module_type: str, 
        code: str
    ) -> Optional[StateResponse]:
        """
        根据代码获取状态
        
        Args:
            db: 数据库连接
            module_type: 模块类型
            code: 状态代码（会自动转换为大写进行匹配）
            
        Returns:
            Optional[StateResponse]: 状态信息
        """
        # 统一转换为大写进行比较（因为状态代码在数据库中存储为大写）
        code_upper = code.upper() if code else code
        states = await self.get_module_states(db, module_type)
        for state in states:
            state_code_upper = state.code.upper() if state.code else state.code
            if state_code_upper == code_upper:
                return state
        return None
    
    async def get_enabled_states(
        self, 
        db: AsyncIOMotorDatabase, 
        module_type: str
    ) -> List[StateResponse]:
        """获取启用的状态"""
        states = await self.get_module_states(db, module_type)
        return [state for state in states if state.is_enabled]
    
    async def get_visible_states(
        self, 
        db: AsyncIOMotorDatabase, 
        module_type: str
    ) -> List[StateResponse]:
        """获取可见的状态"""
        states = await self.get_module_states(db, module_type)
        return [state for state in states if state.is_visible]
    
    async def get_default_state(
        self, 
        db: AsyncIOMotorDatabase, 
        module_type: str
    ) -> Optional[StateResponse]:
        """获取默认状态"""
        states = await self.get_module_states(db, module_type)
        for state in states:
            if state.is_default:
                return state
        # 如果没有默认状态，返回 None（不使用备用逻辑）
        return None
    
    async def validate_state_code(
        self, 
        db: AsyncIOMotorDatabase, 
        module_type: str, 
        code: str
    ) -> bool:
        """验证状态代码是否有效"""
        state = await self.get_state_by_code(db, module_type, code)
        return state is not None and state.is_enabled
    
    async def get_state_options(
        self, 
        db: AsyncIOMotorDatabase, 
        module_type: str
    ) -> List[Dict[str, str | bool | None]]:
        """获取状态选项（用于前端下拉框）- 只返回启用的状态"""
        # 只返回启用且可见的状态
        states = await self.get_enabled_states(db, module_type)
        return [
            {
                "label": state.name,
                "value": state.code,
                "color": state.color,
                "icon": state.icon,
                "disabled": False  # 因为是启用的状态，所以都不禁用
            }
            for state in states if state.is_visible  # 同时过滤可见性
        ]
    
    async def get_all_module_states(
        self, 
        db: AsyncIOMotorDatabase
    ) -> Dict[str, List[StateResponse]]:
        """获取所有模块的状态"""
        result = {}
        for module_type in ModuleType:
            result[module_type.value] = await self.get_module_states(db, module_type.value)
        return result
    
    def invalidate_cache(self, module_type: Optional[str] = None):
        """清除缓存"""
        if module_type:
            cache_key = f"module_states_{module_type}"
            self._cache.pop(cache_key, None)
            self._cache_timestamps.pop(cache_key, None)
        else:
            self._cache.clear()
            self._cache_timestamps.clear()
    
    def _is_cache_valid(self, cache_key: str) -> bool:
        """检查缓存是否有效"""
        if cache_key not in self._cache or cache_key not in self._cache_timestamps:
            return False
        
        cache_time = self._cache_timestamps[cache_key]
        return datetime.utcnow() - cache_time < self._cache_ttl
    
    async def generate_typescript_types(
        self, 
        db: AsyncIOMotorDatabase
    ) -> str:
        """生成TypeScript类型定义"""
        all_states = await self.get_all_module_states(db)
        
        type_definitions = []
        
        # 生成每个模块的状态类型
        for module_type, states in all_states.items():
            if not states:
                continue
                
            # 状态代码联合类型
            state_codes = [f"'{state.code}'" for state in states]
            type_name = f"{module_type.capitalize()}Status"
            type_definitions.append(f"export type {type_name} = {' | '.join(state_codes)};")
            
            # 状态选项类型
            options_type_name = f"{module_type.capitalize()}StatusOption"
            type_definitions.append(f"""
export interface {options_type_name} {{
  label: string;
  value: {type_name};
  color: string;
  icon?: string;
  disabled?: boolean;
}}""")
            
            # 状态常量
            const_name = f"{module_type.upper()}_STATUS_OPTIONS"
            options = []
            for state in states:
                options.append(f"""  {{
    label: '{state.name}',
    value: '{state.code}',
    color: '{state.color}',
    icon: {f"'{state.icon}'" if state.icon else 'undefined'},
    disabled: {str(not state.is_enabled).lower()}
  }}""")
            
            options_joined = "\n".join(options)
            type_definitions.append(
                f"export const {const_name}: {options_type_name}[] = [\n{options_joined}\n];"
            )
        
        # 生成通用状态接口
        type_definitions.append("""
export interface StateInfo {
  id: string;
  name: string;
  code: string;
  module_type: string;
  description?: string;
  color: string;
  icon?: string;
  sort_order: number;
  is_enabled: boolean;
  is_visible: boolean;
  is_default: boolean;
  created_at?: string;
  updated_at?: string;
}

export interface StateOption {
  label: string;
  value: string;
  color: string;
  icon?: string;
  disabled?: boolean;
}"""
)
        
        return "\n".join(type_definitions)


# 全局状态缓存实例
state_cache = StateCacheManager()